Create Least Privilege Policies
As part of your account preparation, you will create least privilege policies—individual policies you will attach to your cross-account role that allow CloudCheckr to access the AWS data it needs to create its reports.
Each least privilege policy provides permissions to a core function in our application:
- Cost
- Billing
- Security/Compliance
- Inventory
- CloudTrail
- CloudWatch Flow Logs
In theory, it may seem like one big policy would be easier to manage. But, by applying only selected policies, you ensures that whoever uses the cross-account role only has access to the permissions they need to do their job—and nothing more.
This procedure will show you how to create the least privileged policies in the AWS Management Console.
Procedure
- Log in to the AWS Management Console.
The AWS services page opens. - Scroll down to the Security, Identity & Compliance section and select IAM.The Welcome to Identity and Access Management screen displays.
- From the dashboard, click Policies. A list of policies displays.
- Click Create policy.
The Create Policy page opens. - For each core function of CloudCheckr that you want a cross-account role to have access to, follow these steps:
- Click a button to display the selected policy document.
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"CloudCheckrCostPermissions",
"Effect":"Allow",
"Action":[
"ce:GetReservationUtilization",
"ce:GetSavingsPlansPurchaseRecommendation",
"ec2:DescribeAccountAttributes",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeReservedInstancesOfferings",
"ec2:DescribeReservedInstances",
"ec2:DescribeReservedInstancesListings",
"ec2:DescribeHostReservationOfferings",
"ec2:DescribeReservedInstancesModifications",
"ec2:DescribeHostReservations",
"ec2:DescribeInstances",
"ec2:DescribeInstanceStatus",
"ec2:DescribeRegions",
"ec2:DescribeKeyPairs",
"ec2:DescribePlacementGroups",
"ec2:DescribeAddresses",
"ec2:DescribeSpotInstanceRequests",
"ec2:DescribeImages",
"ec2:DescribeImageAttribute",
"ec2:DescribeSnapshots",
"ec2:DescribeVolumes",
"ec2:DescribeTags",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeSecurityGroups",
"ec2:DescribeInstanceAttribute",
"ec2:DescribeVolumeStatus",
"elasticache:DescribeReservedCacheNodes",
"elasticache:DescribeReservedCacheNodesOfferings",
"rds:DescribeReservedDBInstances",
"rds:DescribeReservedDBInstancesOfferings",
"rds:DescribeDBInstances",
"redshift:DescribeReservedNodes",
"redshift:DescribeReservedNodeOfferings",
"s3:GetBucketACL",
"s3:GetBucketLocation",
"s3:GetBucketLogging",
"s3:GetBucketPolicy",
"s3:GetBucketTagging",
"s3:GetBucketWebsite",
"s3:GetBucketNotification",
"s3:GetLifecycleConfiguration",
"s3:List*",
"dynamodb:DescribeReservedCapacity",
"dynamodb:DescribeReservedCapacityOfferings",
"iam:GetAccountAuthorizationDetails",
"iam:ListRolePolicies",
"iam:ListAttachedRolePolicies",
"savingsplans:DescribeSavingsPlans"
],
"Resource":"*"
}
]
}{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"CostReadDBR",
"Effect":"Allow",
"Action":[
"s3:GetBucketACL",
"s3:GetBucketLocation",
"s3:GetBucketLogging",
"s3:GetBucketPolicy",
"s3:GetBucketTagging",
"s3:GetBucketWebsite",
"s3:GetBucketNotification",
"s3:GetLifecycleConfiguration",
"s3:GetNotificationConfiguration",
"s3:GetObject"
],
"Resource":[
"arn:aws:s3:::[YOUR DETAILED BILLING REPORT BUCKET]",
"arn:aws:s3:::[YOUR DETAILED BILLING REPORT BUCKET]/*"
]
}
]
}{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"CostReadCUR",
"Effect":"Allow",
"Action":[
"s3:GetObject"
],
"Resource":[
"arn:aws:s3:::[YOUR COST AND USAGE REPORT BUCKET]",
"arn:aws:s3:::[YOUR COST AND USAGE REPORT BUCKET]/*"
]
}
]
}{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"Stmt1443712554000",
"Effect":"Allow",
"Action":[
"s3:DeleteObject",
"s3:GetBucketLocation",
"s3:ListObject",
"s3:PutObject",
],
"Resource":[
"arn:aws:s3:::your-target-S3-bucket-name-here*"
]
}
]
}{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"SecurityPermissons",
"Effect":"Allow",
"Action":[
"acm:DescribeCertificate",
"acm:ListCertificates",
"acm:GetCertificate",
"cloudtrail:DescribeTrails",
"cloudtrail:GetTrailStatus",
"logs:GetLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"config:DescribeConfigRules",
"config:GetComplianceDetailsByConfigRule",
"config:DescribeDeliveryChannels",
"config:DescribeDeliveryChannelStatus",
"config:DescribeConfigurationRecorders",
"config:DescribeConfigurationRecorderStatus",
"ec2:Describe*",
"iam:Get*",
"iam:List*",
"iam:GenerateCredentialReport",
"kms:DescribeKey",
"kms:GetKeyPolicy",
"kms:GetKeyRotationStatus",
"kms:ListAliases",
"kms:ListGrants",
"kms:ListKeys",
"kms:ListKeyPolicies",
"kms:ListResourceTags",
"rds:Describe*",
"ses:ListIdentities",
"ses:GetSendStatistics",
"ses:GetIdentityDkimAttributes",
"ses:GetIdentityVerificationAttributes",
"ses:GetSendQuota",
"sns:GetSnsTopic",
"sns:GetTopicAttributes",
"sns:GetSubscriptionAttributes",
"sns:ListTopics",
"sns:ListSubscriptionsByTopic",
"sqs:ListQueues",
"sqs:GetQueueAttributes"
],
"Resource":"*"
}
]
}{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"InventoryAndUtilization",
"Effect":"Allow",
"Action":[
"access-analyzer:List*",
"acm:DescribeCertificate",
"acm:ListCertificates",
"acm:GetCertificate",
"ec2:Describe*",
"ec2:GetConsoleOutput",
"ec2:GetEbsEncryptionByDefault",
"autoscaling:Describe*",
"cloudformation:DescribeStacks",
"cloudformation:GetStackPolicy",
"cloudformation:GetTemplate",
"cloudformation:ListStacks",
"cloudformation:ListStackResources",
"cloudfront:List*",
"cloudfront:GetDistributionConfig",
"cloudfront:GetStreamingDistributionConfig",
"cloudhsm:Describe*",
"cloudhsm:List*",
"cloudsearch:Describe*",
"cloudtrail:DescribeTrails",
"cloudtrail:GetEventSelectors",
"cloudtrail:GetTrailStatus",
"cloudwatch:DescribeAlarms",
"cloudwatch:GetMetricStatistics",
"cloudwatch:ListMetrics",
"cognito-identity:ListIdentities",
"cognito-identity:ListIdentityPools",
"cognito-idp:ListGroups",
"cognito-idp:ListIdentityProviders",
"cognito-idp:ListUserPools",
"cognito-idp:ListUsers",
"cognito-idp:ListUsersInGroup",
"config:DescribeConfigRules",
"config:GetComplianceDetailsByConfigRule",
"config:Describe*",
"datapipeline:ListPipelines",
"datapipeline:GetPipelineDefinition",
"datapipeline:DescribePipelines",
"directconnect:DescribeLocations",
"directconnect:DescribeConnections",
"directconnect:DescribeVirtualInterfaces",
"dynamodb:ListTables",
"dynamodb:DescribeTable",
"dynamodb:ListTagsOfResource",
"ecs:ListClusters",
"ecs:DescribeClusters",
"ecs:ListContainerInstances",
"ecs:DescribeContainerInstances",
"ecs:ListServices",
"ecs:DescribeServices",
"ecs:ListTaskDefinitions",
"ecs:ListTaskDefinitionFamilies",
"ecs:DescribeTaskDefinition",
"ecs:ListTasks",
"ecs:DescribeTasks",
"ssm:ListResourceDataSync",
"ssm:ListAssociations",
"ssm:ListDocumentVersions",
"ssm:ListDocuments",
"ssm:ListInstanceAssociations",
"ssm:ListInventoryEntries",
"elasticache:Describe*",
"elasticache:List*",
"elasticbeanstalk:Describe*",
"elasticfilesystem:DescribeFileSystems",
"elasticfilesystem:DescribeTags",
"elasticloadbalancing:Describe*",
"elasticmapreduce:Describe*",
"elasticmapreduce:List*",
"es:ListDomainNames",
"es:ListTags",
"es:DescribeElasticsearchDomains",
"es:DescribeReservedElasticsearchInstances",
"es:DescribeElasticsearchDomains",
"glacier:ListTagsForVault",
"glacier:DescribeVault",
"glacier:GetVaultNotifications",
"glacier:DescribeJob",
"glacier:GetJobOutput",
"glacier:ListJobs",
"glacier:ListVaults",
"iam:Get*",
"iam:List*",
"iam:GenerateCredentialReport",
"iot:DescribeThing",
"iot:ListThings",
"kms:DescribeKey",
"kms:GetKeyPolicy",
"kms:GetKeyRotationStatus",
"kms:ListAliases",
"kms:ListGrants",
"kms:ListKeys",
"kms:ListKeyPolicies",
"kms:ListResourceTags",
"kinesis:ListStreams",
"kinesis:DescribeStream",
"kinesis:GetShardIterator",
"kinesis:ListTagsForStream",
"lambda:ListFunctions",
"lambda:ListTags",
"Organizations:List*",
"Organizations:Describe*",
"rds:Describe*",
"rds:List*",
"redshift:Describe*",
"route53:ListHealthChecks",
"route53:ListHostedZones",
"route53:ListResourceRecordSets",
"s3:GetBucketACL",
"s3:GetBucketLocation",
"s3:GetBucketLogging",
"s3:GetBucketPolicy",
"s3:GetBucketPublicAccessBlock",
"s3:GetBucketTagging",
"s3:GetBucketVersioning",
"s3:GetBucketWebsite",
"s3:GetBucketNotification",
"s3:GetLifecycleConfiguration",
"s3:List*",
"sdb:ListDomains",
"sdb:DomainMetadata",
"ses:ListIdentities",
"ses:GetSendStatistics",
"ses:GetIdentityDkimAttributes",
"ses:GetIdentityVerificationAttributes",
"ses:GetSendQuota",
"sns:GetTopicAttributes",
"sns:GetSubscriptionAttributes",
"sns:ListTopics",
"sns:ListSubscriptionsByTopic",
"sqs:ListQueues",
"sqs:GetQueueAttributes",
"storagegateway:Describe*",
"storagegateway:List*",
"support:*",
"swf:ListClosedWorkflowExecutions",
"swf:ListDomains",
"swf:ListActivityTypes",
"swf:ListWorkflowTypes",
"wellarchitected:Get*",
"wellarchitected:List*",
"workspaces:DescribeWorkspaceDirectories",
"workspaces:DescribeWorkspaceBundles",
"workspaces:DescribeWorkspaces"
],
"Resource":"*"
}
]
}{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"CloudTrailPermissions",
"Effect":"Allow",
"Action":[
"s3:GetBucketACL",
"s3:GetBucketLocation",
"s3:GetBucketLogging",
"s3:GetBucketPolicy",
"s3:GetBucketTagging",
"s3:GetBucketWebsite",
"s3:GetBucketNotification",
"s3:GetLifecycleConfiguration",
"s3:GetNotificationConfiguration",
"s3:GetObject",
"s3:List*"
],
"Resource":[
"arn:aws:s3:::[YOUR CLOUDTRAIL BUCKET]",
"arn:aws:s3:::[YOUR CLOUDTRAIL BUCKET]/*"
]
}
]
}
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"CloudWatchLogsSpecific",
"Effect":"Allow",
"Action":[
"logs:GetLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
],
"Resource":[
"arn:aws:logs:*:*:*"
]
}
]
}
- Copy the entire contents of the policy document to your clipboard.
- Return to the Create Policy page in the AWS Management Console.
- Click the JSON tab.
- Replace the text in the JSON tab with the policy you just copied.
For Billing and CloudTrail policies, replace the dummy S3 bucket name with the name of the S3 bucket where AWS stores your billing report.
- Click Review policy.
The Review policy page opens. - Type a name for the policy and click Create policy.
A message at the top of the policy page indicates that your policy has been created.
- Click a button to display the selected policy document.
- Repeat step 5 for each least privilege policy you want to attach to your cross-account role.
If you are preparing your account for the first time and creating a cross-account role manually, continue to: Create a Cross-Account Role Manually.
Policy Structure Notes
s3:GetObject
permissions. But, you can add the s3:GetObject
permission to the required reports.s3:GetEncryptionConfiguration
by default. However, without this permission, CloudCheckr cannot get the information it needs to report on the S3 Bucket Without Default Encryption Enabled Best Practice Check (BPC). If you decide not to add this permission to your policy, we recommend that you ignore or disable this BPC to avoid any false negatives.